
package com.craterhill.java.ems.web.authenticator;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.sql.DataSource;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;

import com.craterhill.java.ems.common.beans.Role;
import com.craterhill.java.ems.common.beans.Staff;
import com.craterhill.java.ems.dao.StaffDao;
import com.craterhill.java.ems.dao.impl.StaffDaoImpl;

public class StaffAuthenticator implements AuthenticationProvider {

	private StaffDao staffDao;
	private DataSource dataSource;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {

		this.staffDao = new StaffDaoImpl(getDataSource());

		String username = (String) authentication.getPrincipal();
		String password = (String) authentication.getCredentials();

		UsernamePasswordAuthenticationToken request = (UsernamePasswordAuthenticationToken) authentication;
		Set<GrantedAuthority> authorities = null;

		Staff staff = staffDao.findByUsernameAndPassword(username, password);
		if(staff != null){
			List<Role> userRoles = staffDao.findStaffAuthorities(staff.getStaffId());
			if(!userRoles.isEmpty()){
				authorities = new HashSet<GrantedAuthority>();
				for(Role userRole : userRoles){
					authorities.add(new CHTCGrantedAuthority(userRole.getRoleName()));
				}

				CHTCAuthenticatorToken chtCAuthenticatorToken = new CHTCAuthenticatorToken(request.getPrincipal(), request.getCredentials(),
						new ArrayList<GrantedAuthority>(authorities));
				chtCAuthenticatorToken.setUserId(staff.getStaffId());
				chtCAuthenticatorToken.setLoggedStaff(staff);
				return chtCAuthenticatorToken;
			}
		}
		return null;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public DataSource getDataSource() {
		return dataSource;
	}
}
